#ifndef __RedirectionData_h__
#define __RedirectionData_h__

#include "Handle.h"

class CMyOverlapped;




class CRedirectionTarget
{
public:
	void Initialise (const std::string& p_strName);
	const std::string& GetName (void) const { return m_strName; }
	const std::string& GetAccumulatedText (void) const { return m_strAccumulatedText; }
	const CHandle& GetPipeReadingHandle (void) const { return m_hPipeRead; }
	const CHandle& GetPipeWritingHandle (void) const { return m_hPipeWrite; }
	const CHandle& GetFinishedReadingEvent (void) const { return m_hFinishedReadingEvent; }

	void ClearAccumulatedText (void) { m_strAccumulatedText.clear(); }
	void CloseReadingEnd (void) { m_hPipeRead.Close (); }
	void CloseWritingEnd (void) { m_hPipeWrite.Close (); }
	void Reset (void)
	{
		ClearAccumulatedText ();
		CloseReadingEnd ();
		CloseWritingEnd ();
		m_hFinishedReadingEvent.Close ();
	}
	//DWORD BeginReading (CMyOverlapped *ovp) { return StartAsyncRead (ovp); }

	DWORD StartAsyncRead (CMyOverlapped *ovp);

private:

	std::string m_strName;
	void AccumulateText (LPCTSTR p_lpszText);


	static void CALLBACK StaticReadCompletionRoutine (
		DWORD			p_dwErrorCode,
		DWORD			p_dwNumberOfBytesTransferred,
		LPOVERLAPPED	p_pOverlapped);

	void InstanceReadCompletionRoutine (
		DWORD			p_dwErrorCode,
		DWORD			p_dwNumberOfBytesTransferred,
		CMyOverlapped*	p_pMyOverlapped);

	// Text read from the child process is accumulated in this field.
	std::string m_strAccumulatedText;

	// This handle is used by the parent process to read text from the child process.
	CHandle m_hPipeRead;

	// This handle is inherited by the child process.
	CHandle m_hPipeWrite;

	// We set this event when :-
	//	- an error occurs reading from the pipe
	// or
	//	- we read 0 bytes
	CHandle	m_hFinishedReadingEvent;
};



const static DWORD BUFFER_SIZE = 256;

class CMyOverlapped : public OVERLAPPED
{
public:
	CMyOverlapped (CRedirectionTarget& p_rThis,void *param) :
		m_rThis (p_rThis),ctxParam(param)
	{
		// Zero-out the OVERLAPPED part of this instance.
		// OVERLAPPED is a typedef struct so it does not
		// have its own constructor.
		ZeroMemory (this, sizeof (OVERLAPPED));

		// Zero-out the buffer.
		ZeroMemory (m_Buffer, sizeof (m_Buffer));
	}

	LPVOID GetBufferAddress (void) { return m_Buffer; }
	LPCVOID GetBufferAddress (void) const { return m_Buffer; }
	DWORD GetBufferSize (void) const { return BUFFER_SIZE; }
	CRedirectionTarget& GetThis (void) { return m_rThis; }

	LPVOID GetParam(){return ctxParam;};
private:
	CRedirectionTarget& m_rThis;
	void * ctxParam;
	// ANSI char buffer. Includes an extra byte for the NULL terminator.
	CHAR m_Buffer[BUFFER_SIZE + 1];
};
#endif
